﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using TBR.Repositories;
using TBR.Entities;
using System.Windows.Data;
using TBR.Resources;

namespace TBR
{
    public partial class PeoplePage : PhoneApplicationPage
    {
        #region PrivateVariable

        static int nextPage = 1;
       
        static bool endList = false;

        private ScrollViewer _listScrollViewerFriends;
      
        private ScrollViewer _listScrollViewerGuests;
       
        private ScrollViewer _listScrollViewerInvocations;

        public static readonly DependencyProperty ListVerticalOffsetProperty = DependencyProperty.Register(
      "ListVerticalOffset",
      typeof(double),
      typeof(PeoplePage),
      new PropertyMetadata(new PropertyChangedCallback(OnListVerticalOffsetChanged)));

        private double _lastFetch;

        static ProgressIndicator indicator = new ProgressIndicator();

        private static FriendsRepository friendsRepository = null;
        private static GuestRepository guestsRepository = null;
        private static InvitesRepository invitesRepository = null;

        IList<User> profile = new List<User>();

        object lockObject = new object();
        #endregion

        #region Properties
        public double ListVerticalOffset
        {
            get { return (double)this.GetValue(ListVerticalOffsetProperty); }
            set { this.SetValue(ListVerticalOffsetProperty, value); }
        }

        public ScrollViewer ListScrollViewer
        {
            get
            {
                switch (((PanoramaItem)Panorama.DefaultItem).Name)
                {
                    case "FriendsPage":
                        {
                            return _listScrollViewerFriends;
                        }
                    case "GuestPage":
                        {
                            return _listScrollViewerGuests;
                        }
                    case "InvitesPage":
                        {
                            return _listScrollViewerInvocations;
                        }

                    default: return new ScrollViewer();
                }
            }
        }
        #endregion

        #region Constructors
        public PeoplePage()
        {
            try
            {              
                InitializeComponent();

            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message + "\n" + exc.StackTrace);
            }
        }
        #endregion

        #region PrivateMethods
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            nextPage = 1;
            base.OnNavigatedTo(e);

            string page = String.Empty;

           
            if (NavigationContext.QueryString.TryGetValue("page", out page))
            {
                switch (page)
                {
                    case "Friends":
                        {
                            Panorama.DefaultItem = FriendsPage;
                            // ScrollViewerBinding(scrollViewerGuest);
                            break;
                        }
                    case "Guests":
                        {
                            Panorama.DefaultItem = GuestPage;
                            break;
                        }
                    case "Invocations":
                        {
                            Panorama.DefaultItem = InvitesPage;
                            break;
                        }

                    default: break;
                }

            }
            
            LoadPage();
        }
        private void ScrollViewerBinding()
        {
            try
            {
                Binding binding = new Binding();
                binding.Source = ListScrollViewer;
                binding.Path = new PropertyPath("VerticalOffset");
                binding.Mode = BindingMode.OneWay;
                this.SetBinding(ListVerticalOffsetProperty, binding);
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message + "\n" + exc.StackTrace);
            }
        }

        private void ScrollViewerGuests_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                _listScrollViewerGuests = sender as ScrollViewer;
                ScrollViewerBinding();
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message + "\n" + exc.StackTrace);
            }
        }

        private void ScrollViewerFriends_Loaded(object sender, RoutedEventArgs e)
        {
            try
            { 
                _listScrollViewerFriends = sender as ScrollViewer;
                ScrollViewerBinding();

            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message + "\n" + exc.StackTrace);
            }
        }
        private void ScrollViewerInvocations_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                _listScrollViewerInvocations = sender as ScrollViewer;
                ScrollViewerBinding();

            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message + "\n" + exc.StackTrace);
            }
        }

        private static void OnListVerticalOffsetChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            try
            {
                if (!endList)
                {
                    PeoplePage page = obj as PeoplePage;
                    ScrollViewer viewer = page.ListScrollViewer;

                    if (viewer != null)
                    {
                        if (page._lastFetch < viewer.ScrollableHeight)
                        {
                            // Trigger within 1/4 the viewport.
                            if (viewer.VerticalOffset >= viewer.ScrollableHeight - viewer.ViewportHeight / 4)
                            {
                                page._lastFetch = viewer.ScrollableHeight;

                                page.LoadPage();
                            }
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message + "\n" + exc.StackTrace);
            }
        }
      
        private void friendsRepository_GetFriendsCompleted(object source, FriendsRepository.RequestEventArgs args)
        {
            if (args.Friends.Count == 0) endList = true;
            foreach (var friend in args.Friends)
            {
                if (profile.Any(f => f.Id == friend.Id)) { endList = true; break; }
                profile.Add(friend);
                PostList.Items.Add(friend);
            }
            indicator.IsVisible = false;
        }
        void guestsRepository_GetGuestCompleted(object source, GuestRepository.RequestEventArgs args)
        {
            if (args.Guests.Count == 0) endList = true;
         
            foreach (var guest in args.Guests)
            {
                if (profile.Any(f => f.Id == guest.Id)) { endList = true; break; }
                profile.Add(guest);
                GuestsList.Items.Add(guest);
            }
            indicator.IsVisible = false;
        }

        void invitesRepository_GetInvitesPageCompleted(object source, InvitesRepository.RequestEventArgs args)
        {
            if (args.Invites.Count == 0) endList = true;

            foreach (var invite in args.Invites)
            {
                if (profile.Any(f => f.Id == invite.Id)) { endList = true; break; }
                profile.Add(invite);
                InvitesList.Items.Add(invite);
            }
            indicator.IsVisible = false;
        }
        private void Panorama_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            nextPage = 1;
            endList = false;
            _lastFetch = 0;
            Panorama.DefaultItem = e.AddedItems[0];
            
            profile = new List<User>();
            GuestsList.Items.Clear();
            PostList.Items.Clear();
            InvitesList.Items.Clear();
            ScrollViewerBinding();
            LoadPage();
        }

       
        private void ProgessLoading()
        {
            indicator.IsVisible = true;
            indicator.IsIndeterminate = true;
            indicator.Text = AppResources.txtLoading; ;
            SystemTray.SetProgressIndicator(this, indicator);
        }
         
        private void LoadPage()
        {
            
            lock (lockObject)
            {
                ProgessLoading();

            switch (((PanoramaItem)Panorama.DefaultItem).Name)
            {
                case "FriendsPage":
                    {
                        LoadFriendsPage();
                        break;
                    }
                case "GuestPage":
                    {
                        LoadGuestPage();
                        break;
                    }
                case "InvitesPage":
                    {
                        LoadInvitesPage();
                        break;
                    }

                default: break;
            }
            nextPage++;
            }
        }

        private void LoadInvitesPage()
        {
            invitesRepository = new InvitesRepository();
            invitesRepository.GetInvitesPageCompleted += invitesRepository_GetInvitesPageCompleted;
            invitesRepository.GetInvites();
        }

    

        private void LoadGuestPage()
        {
            guestsRepository = new GuestRepository();
            guestsRepository.GetGuestCompleted += guestsRepository_GetGuestCompleted;
            guestsRepository.GetGuests(nextPage);
        }
      

        private void LoadFriendsPage()
        {
            friendsRepository = new FriendsRepository(); 
            friendsRepository.GetFriendsPageCompleted += friendsRepository_GetFriendsCompleted;
            friendsRepository.GoFrieds(nextPage);
        }
        #endregion
    }
}